home *** CD-ROM | disk | FTP | other *** search
- /*==================================================================
- File: ZStringDictionary.cpp
-
- Contains: Class for parsing named ZStrings into platform-
- specific strings.
-
- Written by: Eric Traut
-
- Copyright: 2000-2001 Connectix Corporation
-
- This source has been placed into the public domain by
- Connectix Corporation. You have the right to modify,
- distribute or use this code without any legal limitations
- or finanicial/licensing requirements. Connectix is not
- liable for any problems that result from the use of this
- code.
-
- If you have comments, feedback, questions, or would like
- to submit bug fixes or updates to this code, please email
- opensource@connectix.com.
- ==================================================================*/
-
- #include "ZStringDictionary.h"
- #include "ZString.h"
-
- #include <stdlib.h>
- #include <new>
-
-
- /*==================================================================
-
- Explanation:
-
- This module implements a simple dictionary that associates
- string path names with their values. Each path name is
- delimited by "/" characters.
-
- The class currently assumes that the name string is statically
- allocated and will not go away. We can change this assumption
- in the future if we want to make copies of the string name
- at registration time.
-
- Currently, the dictionary is implemented as a simple hash table.
- In the future, we may want to go with a more complex tree
- structure of some sort that follows the path hierarchy.
-
- ==================================================================*/
-
-
- ZStringDictionary * ZStringDictionary::sDictionary = NULL;
-
-
- /*------------------------------------------------------------------
- ZStringDictionary
- ------------------------------------------------------------------*/
-
- ZStringDictionary::ZStringDictionary()
- {
- // This is a singleton class
- check(sDictionary == NULL);
- sDictionary = this;
-
- // Zero out the hash table.
- memset(mDictionaryHash, 0, sizeof(mDictionaryHash));
- }
-
-
- /*------------------------------------------------------------------
- ~ZStringDictionary
- ------------------------------------------------------------------*/
-
- ZStringDictionary::~ZStringDictionary()
- {
- check(sDictionary == this);
- sDictionary = NULL;
-
- // Now, delete all the strings. Their underlying data
- // will go away if their ref counts go to zero after
- // the dictionary stops referring to them.
- Z_UInt32 entryIndex;
- for (entryIndex = 0; entryIndex < kZDictionaryHashEntries; entryIndex++)
- {
- ZDictionaryEntry * curEntry = mDictionaryHash[entryIndex];
- ZDictionaryEntry * nextEntry;
-
- while (curEntry != NULL)
- {
- nextEntry = curEntry->mNext;
-
- delete curEntry;
-
- curEntry = nextEntry;
- }
- }
- }
-
-
- /*------------------------------------------------------------------
- LookUpString
- ------------------------------------------------------------------*/
-
- Z_Boolean
- ZStringDictionary::LookUpString(
- const ZStringParseInfo & inParseInfo,
- ZString & outZString)
- {
- Z_UInt32 entryIndex = HashString(inParseInfo.fNameStr, inParseInfo.fNameStrLen);
- ZDictionaryEntry * curEntry = mDictionaryHash[entryIndex];
-
- while (curEntry != NULL)
- {
- // Do the lengths match?
- if (curEntry->mNameStrLen == inParseInfo.fNameStrLen)
- {
- Z_UInt32 curCharIndex;
- Z_Boolean stringsMatch = true;
-
- for (curCharIndex = 0; curCharIndex < curEntry->mNameStrLen; curCharIndex++)
- {
- if (curEntry->mNameStr[curCharIndex] != inParseInfo.fNameStr[curCharIndex])
- {
- stringsMatch = false;
- break;
- }
- }
-
- // Did we find a match? If so, return the string.
- if (stringsMatch)
- {
- outZString = curEntry->mString;
- return true;
- }
- }
-
- curEntry = curEntry->mNext;
- }
-
- return false;
- }
-
-
- /*------------------------------------------------------------------
- RegisterString
- ------------------------------------------------------------------*/
-
- void
- ZStringDictionary::RegisterString(
- const ZStringParseInfo & inParseInfo,
- ZString & inZString)
- {
- // The caller should have already verified that
- // the string is not registered already.
-
- ZDictionaryEntry * newEntry = new (std::nothrow) ZDictionaryEntry(inParseInfo.fNameStr, inParseInfo.fNameStrLen, inParseInfo.fIsVolatile);
- Z_UInt32 entryIndex = HashString(inParseInfo.fNameStr, inParseInfo.fNameStrLen);
-
- if (newEntry != NULL) // entry was allocated
- {
- if (newEntry->mNameStr == NULL) // copy of name was not allocated
- { delete newEntry; }
- else // copy of name allocated or not needed
- {
- newEntry->mString = inZString;
- newEntry->mNext = mDictionaryHash[entryIndex];
- mDictionaryHash[entryIndex] = newEntry;
- }
- }
- }
-
-
- /*------------------------------------------------------------------
- HashString
- ------------------------------------------------------------------*/
-
- Z_UInt32
- ZStringDictionary::HashString(
- const char * inName,
- Z_UInt16 inNameLen)
- {
- Z_UInt16 hashValue = 0;
- Z_UInt16 charsLeft = inNameLen;
- const char * curChar = inName;
-
- while (charsLeft > 0)
- {
- hashValue <<= 1;
- hashValue += *curChar;
-
- curChar++;
- charsLeft--;
- }
-
- return (hashValue & kZDictionaryEntryMask);
- }
-
- #pragma mark -
-
- /*------------------------------------------------------------------
- ZDictionaryEntry
- ------------------------------------------------------------------*/
-
- ZDictionaryEntry::ZDictionaryEntry(
- const char * inNameStr,
- Z_UInt16 inNameStrLen,
- Z_Boolean inCopyNameData)
- : mString(),
- mNameStr(inNameStr),
- mNameStrLen(inNameStrLen),
- mDictionaryOwnsNameData(inCopyNameData),
- mNext(NULL)
- {
- check(mNameStr != NULL);
-
- // Create copy of name data if necessary
- if (mDictionaryOwnsNameData)
- {
- Z_UInt8 * nameCopy = new (std::nothrow) Z_UInt8[inNameStrLen];
- if (nameCopy == NULL) // allocate failed
- {
- mNameStr = NULL;
- mNameStrLen = 0;
- }
- else // allocate succeeded
- {
- // Copy the data
- memcpy(nameCopy, inNameStr, inNameStrLen);
- mNameStr = reinterpret_cast<char *>(nameCopy);
- mNameStrLen = inNameStrLen;
- }
- }
- }
-
-
- /*------------------------------------------------------------------
- ~ZDictionaryEntry
- ------------------------------------------------------------------*/
-
- ZDictionaryEntry::~ZDictionaryEntry(void)
- {
- // Delete copy of name data if necessary
- if (mDictionaryOwnsNameData && mNameStr != NULL)
- {
- delete [] (Z_UInt8 *)mNameStr;
- }
- }
-
-
-